/* Para que ande el strnlen */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif /*_GNU_SOURCE*/

#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>
#include "key.h"
#include "bool.h"



struct skey {
  char *d;
};

key 
key_empty(void)
{
  key k;
  
  k=(key)malloc(sizeof(struct skey));
  k->d=NULL;

  
  assert((k->d)==NULL);

  return k;
}

/*
  DESC: Construye un dato vacio. 
  PRE: { k = NULL }
  k = key_empty();
  POS: {  Hay memoria ==> k --> empty 
  ! Hay memoria ==> k == NULL }
*/

key 
key_destroy(key k)
{
  
  if ((k->d)!=NULL)
	{	
		free(k->d);         /*Libero el campo*/
  	(k->d) =NULL;
  	}
  

  free(k);            /*Libero lo que esta apuntado por el puntero*/
  k=NULL;

  assert(k==NULL);

  return k;
}

/*
  DESC: Destructor del tipo. k cambia.
  PRE: { k --> K }
  k = key_destroy(k);
  POS: { Se destruye K /\ k == NULL }
*/

bool 
key_copyStr(key k,const char *s)
{

  
/*clavar primero un free aca, y allocar*/

  k->d=(char*)realloc(k->d,sizeof(char)*(strlen(s)+1));
  
  
  if(k->d!=NULL)
    {
 
	k->d=strcpy(k->d,s);
    }
  
  return (k->d!=NULL);
}

/*
  DESC: Transforma el string en key y lo copia k. 
  Devuelve False si no hay memoria.
  PRE: { k --> K /\ s --> S /\ len(S) <= keyMaxLen}
  b = key_copyStr(k,s);  
  POS: {  Hay memoria ==>  b /\ k --> fromStr(S)
  ! Hay memoria ==> !b /\ k --> K }   
*/


char *
key_toStr(const key k)
{
  char *w;

  assert(k != NULL); 
  assert(k->d != NULL);
  w=(char*)malloc(sizeof(char)*(strlen(k->d)+1));
  
  if(k->d!=NULL)
    {
      w=strncpy(w,k->d,strlen(k->d)+1);
    }
  
  return w;
}

/*
  DESC: Devuelve un nuevo string (despues de usarlo hay que liberarlo) que 
  representa la key.
  PRE: { k --> K /\ s = NULL }
  s = key_toStr(k);
  POS: {   Hay memoria ==> s --> toStr(K) 
  ! Hay memoria ==> s == NULL }
*/


key 
key_clone(const key k)
{
  key h;
  
  h=key_empty();
  
   h->d=(char *)malloc(strlen(k->d)*sizeof(char));
  
  if((h->d)!=NULL)
    {
      h->d=strncpy(h->d,k->d,keyMaxLen);
    }
  
  return h;
}

/*
  DESC: Construye una copia.
  PRE: { k1 --> K1 /\ k2 = NULL }
  k2 = key_clone(k1);  
  POS: {  Hay memoria ==> k1 --> K1 /\ k2 --> K1 /\ k1 != k2
  ! Hay memoria ==> k2 == NULL /\ k1 --> K1 }
*/

bool
key_eq(const key k1, const key k2)
{
  
  int n;
  bool b;
  
  
 
  n=strncmp(k1->d,k2->d,strlen(k1->d));

  b=(n==0);
  
  return b;
  
}

/*
  DESC: Igualdad. Se puede usar en expresiones.
  PRE: { k1 --> K1 /\ k2 --> K2 }
  b = key_eq(k1,k2);  
  POS: { b == (K1 = K2) }
*/

bool
key_le(const key k1, const key k2)
{
  int n;
  bool b;
  

  n=strncmp(k1->d,k2->d,strlen(k1->d));
  
  b=(n<0);
  
  return b;
  
}

/*
  DESC: Menor. Se puede usar en expresiones.
  PRE: { k1 --> K1 /\ k2 --> K2 }
  b = key_le(k1,k2);  
  POS: { b == (K1 < K2) }
*/
